package com.hyjx.framework.uc.menu;

import com.hyjx.framework.common.CommonUtil;
import com.hyjx.framework.common.tree.TreeObject;
import com.hyjx.framework.common.util.SpringBeanUtil;
import com.hyjx.framework.orm.dao.IBaseDao;
import com.hyjx.framework.orm.dao.Pager;
import com.hyjx.framework.service.RightManager;
import com.hyjx.framework.service.UserCenterService;
import com.hyjx.framework.service.model.CacheMenu;
import com.hyjx.framework.service.model.CacheSubSys;
import com.hyjx.framework.uc.subsys.SubsysModel;
import com.hyjx.framework.uc.subsys.SubsysService;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import javax.annotation.Resource;
import java.sql.SQLException;
import java.util.ArrayList;
import java.util.Collections;
import java.util.Comparator;
import java.util.HashMap;
import java.util.Iterator;
import java.util.List;
import java.util.Map;
import java.util.Map.Entry;

@Service
@Transactional
public class MenuServiceImpl implements MenuService {
    
    @Resource
    private IBaseDao dao;
    
    @Override
    public String queryList(MenuModel model) {
        Pager pager = dao.getPager(model.getModuleName() + ".queryList", model.getModuleName() + ".queryCount", model);
        
        return CommonUtil.getPageJsonStr(pager);
    }
    
    @Override
    public boolean add(MenuModel model) {
        if (dao.addObject(model.getModuleName() + ".insert", model)) {
            //refreshEndflag();
            return true;
        } else {
            return false;
        }
    }
    
    @Override
    public MenuModel getInfoById(MenuModel model) {
        model = (MenuModel) dao.queryObject(model.getModuleName() + ".getInfoById", model);
        return model;
    }
    
    @Override
    public int edit(MenuModel model) {
        return dao.updateObject(model.getModuleName() + ".update", model);
    }
    
    @Override
    public int delete(String ids) {
        int num = 0;
        try {
            String[] id_array = ids.split(",");
            
            for (String id : id_array) {
                MenuModel model = new MenuModel();
                model.setMenu_code(id);
                model = this.getInfoById(model);
                List<MenuModel> list = this.getlListByFather(model);
                if (list.size() == 1) {
                    String parentCode = model.getMenu_parent_code();
                    model.setMenu_code(parentCode);
                    model = this.getInfoById(model);
                    if (model != null) {
                        model.setIs_leaf_node("Y");
                        this.edit(model);
                    }
                }
                dao.deleteObject(model.getModuleName() + ".delete", id);
                dao.deleteObject(model.getModuleName() + ".deleteRoleMenu", id);
                dao.deleteObject(model.getModuleName() + ".deletemenufunc", new HashMap<String, String>().put("menu_code", id));
                num++;
            }
            //refreshEndflag();
            return num;
        } catch (Exception e) {
            e.printStackTrace();
            return num;
        }
    }
    
    @SuppressWarnings("unchecked")
    @Override
    public List<MenuModel> queryMenuModelList(MenuModel model) throws SQLException {
        return dao.queryObjectList(model.getModuleName() + ".queryList", model);
    }
    
    @Override
    public String getmenuTree(MenuModel model) throws SQLException {
        List<MenuModel> list = this.queryMenuModelList(model);
        List<TreeObject> trees = new ArrayList<TreeObject>();
        for (MenuModel m : list) {
            TreeObject to = new TreeObject();
            to.setText(m.getMenu_name());
            to.setCode(m.getMenu_code());
            to.setState("closed");
            to.setId(m.getMenu_code());
            trees.add(to);
        }
        return CommonUtil.getJsonString(trees);
    }
    
    @Override
    public String queryTree(MenuModel model) throws SQLException {
        
        Map<String, CacheSubSys> css = RightManager.getSysMenus();
        List<TreeObject> subList = new ArrayList<TreeObject>();
        for (Entry<String, CacheSubSys> entry : css.entrySet()) {
            List<TreeObject> trees = new ArrayList<TreeObject>();
            List<TreeObject> rootList = new ArrayList<TreeObject>();
            Map<String, TreeObject> map = new HashMap<String, TreeObject>();
            String key = entry.getKey().toString();
            CacheSubSys c = css.get(key);
            SubsysModel sm = c.getSubSys();
            TreeObject t = new TreeObject();
            t.setText(sm.getSubsys_name());
            t.setCode("sys" + sm.getSubsys_id());
            t.setId(sm.getSubsys_id());
            t.setParent_id(null);
            subList.add(t);
            Map<String, CacheMenu> ms = c.getMenus();
            for (Entry<String, CacheMenu> en : ms.entrySet()) {
                String key1 = en.getKey();
                CacheMenu m = ms.get(key1);
                MenuModel mm = m.getMenu();
                TreeObject to = new TreeObject();
                to.setText(mm.getMenu_name());
                to.setCode(mm.getMenu_code());
                to.setId(mm.getMenu_code());
                to.setParent_id(mm.getMenu_parent_code());
                to.setLevelId(mm.getLevelId());
                if ("Y".equals(mm.getIs_leaf_node())) {
                    to.setEndflag("1");
                } else {
                    to.setEndflag("0");
                }
                if (!"Y".equals(mm.getIs_leaf_node()))
                    to.setState("closed");
                map.put(to.getCode(), to);
                trees.add(to);
            }
            for (TreeObject to : trees) {//遍历菜单树的根节点
                //if(to.getParent_id()==null){
                if (to.getParent_id().equals("#")) {
                    t.getChildren().add(to);
                    to.setParent_id(t.getId());
                    rootList.add(to);
                    setchildren(map, to);
                }
            }
        }
        return CommonUtil.getJsonString(subList);
    }
    
    /**
     * 超找当前节点的子节点
     *
     * @param map
     * @param to
     */
    public void setchildren(Map<String, TreeObject> map, TreeObject to) {
        if (to.getEndflag().equals("1"))
            return;
        Iterator<String> iter = map.keySet().iterator();
        while (iter.hasNext()) {
            String key = iter.next();
            TreeObject t = map.get(key);
            if (to.getCode().equals(t.getParent_id())) {
                to.getChildren().add(t);
                Collections.sort(to.getChildren(), new Comparator<TreeObject>() {
                    @Override
                    public int compare(TreeObject o1, TreeObject o2) {
                        //if(o1.getLevelId()!=null&&o2.getLevelId()!=null)
                        return o1.getLevelId().compareTo(o2.getLevelId());
                        
                        
                    }
                    
                });
                setchildren(map, t);
            }
        }
    }
    
    @Override
    public String getrootmax(MenuModel model) throws SQLException {
        return (String) dao.queryObject(model.getModuleName() + ".getrootmax", model);
    }
    
    @SuppressWarnings("unchecked")
    @Override
    public List<MenuModel> queryMenuLevelOne() throws SQLException {
        return dao.queryObjectList(new MenuModel().getModuleName() + ".queryMenuLevelOne");
    }
    
    @Override
    public void refreshEndflag() {
        dao.executeSql("update sys_right_menu a set a.is_leaf_node= case when exists (select 1 from sys_right_menu b where a.menu_code=b.menu_parent_code) then 'N' else 'Y' end");
    }
    
    @SuppressWarnings("unchecked")
    @Override
    public List<MenuModel> getMenuList(MenuModel model) {
        return dao.queryObjectList(model.getModuleName() + ".queryList", model);
    }
    
    @Override
    public String queryFuncList(MenuFunc model) {
        Pager pager = dao.getPager(model.getModuleName() + ".queryFuncList", model.getModuleName() + ".queryFuncCount", model);
        System.out.println(CommonUtil.getPageJsonStr(pager));
        return CommonUtil.getPageJsonStr(pager);
    }
    
    @Override
    public boolean doAddMenuFunc(MenuFunc model) {
        return dao.addObject(model.getModuleName() + ".insertMenuFunc", model);
    }
    
    @Override
    public boolean doEditMenuFunc(MenuFunc model) {
        return dao.addObject(model.getModuleName() + ".updateMenuFunc", model);
    }
    
    @Override
    public MenuFunc findByIdMenuFunc(MenuFunc model) {
        return (MenuFunc) dao.queryObject(model.getModuleName() + ".findByIdMenuFunc", model);
    }
    
    @Override
    public boolean doDeleteMenuFunc(MenuFunc model) {
        int flag = dao.deleteObject(model.getModuleName() + ".deletemenufunc", model);

        return flag > 0;
    }
    
    @Override
    public String buildMenuTreeByCache(String checked, String showOperate, String applyRight, String showSystemId) {
        
        Map<String, CacheSubSys> css = RightManager.getSysMenus();
        List<TreeObject> subList = new ArrayList<TreeObject>();
        
        List<MenuModel> menuList = getUserMenuList(UserCenterService.getCurrentUserInfo().getUser_id());
        String menuCodeStr = "";
        for (MenuModel m : menuList) {
            menuCodeStr = menuCodeStr + "," + m.getMenu_code() + ",";
        }
        
        for (Entry<String, CacheSubSys> entry : css.entrySet()) {
            List<TreeObject> trees = new ArrayList<TreeObject>();
            List<TreeObject> rootList = new ArrayList<TreeObject>();
            Map<String, TreeObject> map = new HashMap<String, TreeObject>();
            String key = entry.getKey();
            CacheSubSys c = css.get(key);
            SubsysModel sm = c.getSubSys();
            
            if (showSystemId != null && !"".equals(showSystemId) && showSystemId.indexOf(sm.getSubsys_id()) < 0) {
                continue;
            }
            
            TreeObject t = new TreeObject();
            t.setText(sm.getSubsys_name());
            t.setCode(sm.getSubsys_id());
            t.setId(sm.getSubsys_id());
            t.setParent_id(null);
            subList.add(t);
            setChecked(checked, t);
            Map<String, CacheMenu> ms = c.getMenus();
            List<Map.Entry<String, CacheMenu>> mappingList = new ArrayList<Map.Entry<String, CacheMenu>>(ms.entrySet());
            for (Entry<String, CacheMenu> entry1 : mappingList) {
                CacheMenu m = entry1.getValue();
                MenuModel mm = m.getMenu();
                if ("1".equals(applyRight)) {//判断是否属于当前用户的菜单
                    if (menuCodeStr.indexOf("," + mm.getMenu_code() + ",") < 0) {
                        continue;
                    }
                }
                TreeObject to = new TreeObject();
                to.setText(mm.getMenu_name());
                to.setCode(mm.getMenu_code());
                to.setId(mm.getMenu_code());
                to.setParent_id(mm.getMenu_parent_code());
                to.setLevelId(mm.getLevelId());
                
                MenuModel modelNew = new MenuModel();
                modelNew.setMenu_parent_code(mm.getMenu_code());
                modelNew.setValidity("Y");
                List<MenuModel> listTmp = getMenuList(modelNew);
                
                //if ("Y".equals(mm.getIs_leaf_node())) {
                if (listTmp.size() <= 0) {
                    to.setEndflag("1");
                } else {
                    to.setEndflag("0");
                }
                //if (!"Y".equals(mm.getIs_leaf_node()))
                if (listTmp.size() >= 1)
                    to.setState("closed");
                
                map.put(to.getCode(), to);
                trees.add(to);
                setChecked(checked, to);
                //if(mm.getIs_leaf_node().equals("Y")){
                if (listTmp.size() <= 0) {
                    if ("1".equals(showOperate))
                        buildChildren(m, to, checked);
                }
            }
            
            for (TreeObject to : trees) {//遍历菜单树的根节点
                if (to.getParent_id().equals("#")) {
                    //if(to.getParent_id()==null){
                    to.setParent_id(t.getId());
                    t.getChildren().add(to);
                    rootList.add(to);
                    setchildren(map, to);
                }
            }
        }
        return CommonUtil.getJsonString(subList);
        
    }
    
    
    @Override
    public String buildMenuTree(String checked, String showOperate, String applyRight, String showSystemId) {
        
        SubsysService subsysSrv = (SubsysService) SpringBeanUtil.getBean("subsysServiceImpl");
        List<SubsysModel> list = subsysSrv.getAllSubsys(new SubsysModel());
        List<MenuModel> menuList = null;
        if ("1".equals(applyRight))//获取所有菜单，包括无效
        {
            menuList = getUserMenuList(UserCenterService.getCurrentUserInfo().getUser_id());
            
        } else {//获取当前用户关联菜单，只包括有效
            try {
                menuList = this.getMenuList(new MenuModel());
            } catch (Exception e) {
                e.printStackTrace();
            }
        }
        List<TreeObject> subList = new ArrayList<TreeObject>();
        for (SubsysModel sm : list) {
            if (showSystemId != null && !"".equals(showSystemId) && showSystemId.indexOf(sm.getSubsys_id()) < 0) {
                continue;
            }
            List<TreeObject> trees = new ArrayList<TreeObject>();
            List<TreeObject> rootList = new ArrayList<TreeObject>();
            Map<String, TreeObject> map = new HashMap<String, TreeObject>();
            TreeObject t = new TreeObject();
            t.setText(sm.getSubsys_name());
            t.setCode(sm.getSubsys_id());
            t.setId(sm.getSubsys_id());
            t.setParent_id(null);
            subList.add(t);
            setChecked(checked, t);
            for (MenuModel mm : menuList) {
                if (mm.getSubsys_id().equals(sm.getSubsys_id())) {
                    TreeObject to = new TreeObject();
                    to.setText(mm.getMenu_name());
                    to.setCode(mm.getMenu_code());
                    to.setId(mm.getMenu_code());
                    to.setParent_id(mm.getMenu_parent_code());
                    to.setLevelId(mm.getLevelId());
                    if ("Y".equals(mm.getIs_leaf_node())) {
                        to.setEndflag("1");
                    } else {
                        to.setEndflag("0");
                    }
                    if (!"Y".equals(mm.getIs_leaf_node()))
                        to.setState("closed");
                    
                    map.put(to.getCode(), to);
                    trees.add(to);
                    setChecked(checked, to);
                    if (mm.getIs_leaf_node().equals("Y")) {
                        if ("1".equals(showOperate))
                            buildChildren(to, checked);
                    }
                }
            }
            
            for (TreeObject to : trees) {//遍历菜单树的根节点
                if (to.getParent_id().equals("#")) {
                    to.setParent_id(t.getId());
                    t.getChildren().add(to);
                    rootList.add(to);
                    setchildren(map, to);
                }
            }
        }
        return CommonUtil.getJsonString(subList);
        
    }
    
    public void setChecked(String checked, TreeObject to) {
        if (checked != null && !"".equals(checked)) {
            if (checked.indexOf("," + to.getId() + ",") != -1) {
                to.setChecked(true);
                to.setSelected(true);
            }
        }
    }
    
    public void buildChildren(CacheMenu m, TreeObject to, String checked) {
        
        MenuFunc model = new MenuFunc();
        model.setMenu_code(to.getCode());
        Map<String, MenuFunc> mfs = m.getOperates();
        for (Entry<String, MenuFunc> entry : mfs.entrySet()) {
            String key = entry.getKey();
            MenuFunc mf = mfs.get(key);
            TreeObject t = new TreeObject();
            t.setId("operate" + mf.getOperate_id());
            t.setParent_id(to.getCode());
            t.setCode(mf.getOperate_id());
            t.setText("<font color=blue>" + mf.getOperate_name() + "</font>");
            if (checked.indexOf("," + mf.getOperate_id() + ",") != -1) {
                t.setChecked(true);
                t.setSelected(true);
            }
            to.getChildren().add(t);
        }
    }
    
    public void buildChildren(TreeObject m, String checked) {
        
        MenuFunc model = new MenuFunc();
        model.setMenu_code(m.getCode());
        List<MenuFunc> funcList = this.selectFuncList(model);
        for (MenuFunc mf : funcList) {
            TreeObject t = new TreeObject();
            t.setId("operate" + mf.getOperate_id());
            t.setParent_id(m.getCode());
            t.setCode(mf.getOperate_id());
            t.setText("<font color=blue>" + mf.getOperate_name() + "</font>");
            if (checked.indexOf("," + mf.getOperate_id() + ",") != -1) {
                t.setChecked(true);
                t.setSelected(true);
            }
            m.getChildren().add(t);
        }
    }
    
    
    public void calcLevelId(MenuModel modelFather, String parentLevelId) {//传过来的应该是父亲节点
        List<MenuModel> children = this.getlListByFather(modelFather);//获取孩子节点,此处已经排好序
        if (children == null || children.size() == 0)
            return;
        
        MenuModel model = new MenuModel();
        model.setMenu_code(modelFather.getMenu_parent_code());
        modelFather = this.getInfoById(model);
        modelFather.setIs_leaf_node("N");
        edit(modelFather);
        Collections.sort(children, new MenuModelSortAsc());
        int i = 1;
        for (MenuModel mm : children) {
            String levelId = String.format("%03d", i);
            mm.setLevelId(parentLevelId + levelId);
            //保存mm修改过后的levelId
            if (edit(mm) > 0) {
                //递归当前节点的子孙节点
                MenuModel m = new MenuModel();
                m.setMenu_parent_code(mm.getMenu_code());
                calcLevelId(m, mm.getLevelId() == null ? "" : mm.getLevelId());
            }
            i++;
        }
    }
    
    @SuppressWarnings("unchecked")
    public List<MenuModel> getlListByFather(MenuModel modelFather) {
        return this.dao.queryObjectList(modelFather.getModuleName() + ".queryTree", modelFather);
    }
    
    private class MenuModelSortAsc implements Comparator<MenuModel> {
        @Override
        public int compare(MenuModel o1, MenuModel o2) {
            if (!o1.getOrder_no().equals(o2.getOrder_no()))
                return Integer.parseInt(o1.getOrder_no()) - Integer.parseInt(o2.getOrder_no());
            else
                return o1.getMenu_code().compareTo(o2.getMenu_code());
        }
    }
    
    @SuppressWarnings("unchecked")
    @Override
    public List<MenuFunc> selectFuncList(MenuFunc model) {
        return this.dao.queryObjectList(model.getModuleName() + ".queryFuncList", model);
    }
    
    @Override
    public String getNewCode(String subsysId, String parentCode) {
        Map<String, CacheSubSys> sysMenus = RightManager.getSysMenus();
        String result = "";
        int flag = 0;
        if (parentCode == null) {
            parentCode = "#";
        }
        for (CacheSubSys subsys : sysMenus.values()) {
            //if(subsys.getSubSys().getSubsys_id().equals(subsysId)){}//去掉同一个子系统的限制
            
            for (CacheMenu menu : subsys.getMenus().values()) {
                //if(parentCode.equals(menu.getMenu().getMenu_parent_code()))
                //System.out.println(menu.getMenu().getMenu_code()+" ===  "+menu.getMenu().getMenu_parent_code());
                // System.out.println(parentCode.length()+"  ===  "+menu.getMenu().getMenu_parent_code().length()+"   ===    "+menu.getMenu().getMenu_parent_code());
                if (parentCode.length() == menu.getMenu().getMenu_parent_code().length()) {
                    String newCode = menu.getMenu().getMenu_code();
                    flag++;
                    if (newCode.compareTo(result) > 0) {
                        result = newCode;
                    }
                }
            }
        }
        
        if ("".equals(result)) {
            return parentCode + "01";
        } else {
            result = "1" + String.format("%02d", flag);
            if ("#".equals(parentCode))
                return "" + String.format("%02d", flag + 1);
            else
                return parentCode + String.format("%02d", flag + 1);
            //return String.valueOf(Long.parseLong(result)+1).substring(1);
        }
    }
    
    @Override
    public List<MenuModel> getUserMenuList(String user_id) {
        return dao.queryObjectList(new MenuModel().getModuleName() + ".getUserMenuList", user_id);
    }
}